#include "CmdParser.h"
#include "../Biz/WWCommonUtility.h"
#include <iostream>
#include <string>
#include <map>
#include <readline/readline.h>
#include <readline/history.h>

using namespace std;
using namespace wwcommon;

static std::string cmdhistoryfile;
CmdParser::CmdParser()
{
    cmdhistoryfile = FileUtility::MakeWWProfileRoot() + "/aliww_cmdhistory";
    read_history(cmdhistoryfile.c_str());
}

CmdParser::~CmdParser()
{
    write_history(cmdhistoryfile.c_str());
}

int CmdParser::ReadCmd()
{
    std::string cmdline;
    char * tmpbuffer;
    tmpbuffer = readline("AliWW Cmd >> ");
    if(tmpbuffer == NULL)
    {
        perror("read command error");
        return -1;
    }
    cmdline = string(tmpbuffer); 
    free(tmpbuffer);

    CommonUtility::TrimStr(cmdline, 3);
    if(!cmdline.empty())
    {
        add_history(cmdline.c_str());
    }
    size_t spos = 0;
    size_t epos = cmdline.find(" ");
    if(epos != std::string::npos)
    {
        std::string tmpstr = cmdline.substr(spos, epos - spos);
        m_current_cmdid = tmpstr;
        m_current_cmdargs = cmdline.substr(epos + 1);
    }
    else
    {
        m_current_cmdid = cmdline.substr(spos);
        m_current_cmdargs.clear();
    }
    std::map<std::string, CmdFuncPtr>::iterator it = m_allCmds.find(m_current_cmdid);
    if(it == m_allCmds.end())
    {
        printf("Unknown command! %s \n", m_current_cmdid.c_str());
        // just wait the next cmd.
        return -1;
    }
    if(it->first == "help")
    {
        if(m_current_cmdargs == "")
        {
            printf("\n");
            printf("All Supported Commands are:\n");
            printf("\n");
            std::map<string, CmdFuncPtr >::const_iterator cit = m_allCmds.begin();
            while(cit != m_allCmds.end())
            {
                printf("%s\t", cit->first.c_str());
                ++cit;
            }
            printf("\n");
            printf("use \"help\" for the Supported command for details.\n");
            return -1;
        }
    }
    if(it->first == "quit")
    {
        //printf("quit command.\n");
        if(m_allCmds.find("quit") != m_allCmds.end())
            m_allCmds["quit"](m_current_cmdargs);
        // need quit the loop of cmd.
        return 0;
    }
    // can excute this cmd.
    return 1;
}

void CmdParser::ExecuteCmd()
{
    if(m_allCmds.find(m_current_cmdid) == m_allCmds.end())
        return;
    m_allCmds[m_current_cmdid](m_current_cmdargs);
}

bool CmdParser::RegisterCmd(const std::string& cmdid, CmdFuncPtr cmdfunc)
{
    if(m_allCmds.find(cmdid) != m_allCmds.end())
        return false;
    if(cmdfunc == NULL)
        return false;
    m_allCmds[cmdid] = cmdfunc;
    return true;
}

